﻿(function () {

    var Earth = function (fieldWidth, fieldHeight) {
        this.width = fieldWidth;
        this.height = fieldHeight;

        this.getBody = [];

        this._levelElementsCount = [];
        this.matrix = [];
        for (var y = 0; y < fieldHeight; y += 1) {
            this.matrix.push([]);
            for (var x = 0; x < fieldWidth; x += 1) {
                this.matrix[y][x] = false;
            }
            this._levelElementsCount[y] = 0;
        }
    };
    Earth.prototype.contains = function (x, y) {
        if (!this.isInRange(x,y)) {
            throw new Error("Block coordinates (" + x + "," + y + ") is out of Earth object bounds");
        }
        if (this.matrix[y][x]) {
            return true;
        }
        return false;
    };
    Earth.prototype.isInRange = function (x,y) {
        return (x >= 0 && x < this.width && y >= 0 && y < this.height);
    };
    Earth.prototype._addBlock = function (block) {
        if (this.contains(block.coordinate.x, block.coordinate.y)) {
            throw new Error("This block " + block.coordinate + " is already contained in Earth object!");
        }        
        this.getBody.push(block);
        this.matrix[block.coordinate.y][block.coordinate.x] = block;
        this._levelElementsCount[block.coordinate.y] += 1;
    };
    Earth.prototype.add = function (fallingObject) {
        for (var i = 0; i < fallingObject.getBody.length; i++) {
            this._addBlock(fallingObject.getBody[i]);
        }
    };
    Earth.prototype._eraseRow = function (rowIndex) {
        for (var i = 0; i < this.width; i++) {
            this.matrix[rowIndex][i] = false;
        }
        this._levelElementsCount[rowIndex] = 0;
    };
    Earth.prototype.updateBodyAndReturnCollapsedRowsCount = function () {
        var rowsCollapsed = 0;
        var levelsToFallDown = [];
        for (var i = this.height - 1; i >= 0; i--) {
            levelsToFallDown[i] = rowsCollapsed;
            if (this._levelElementsCount[i] == this.width) {
                rowsCollapsed++;
                this._eraseRow(i);
            }
        }
        if (rowsCollapsed > 0) {
            this.getBody = [];
            this._levelElementsCount = [];
            for (var y = this.height - 1; y >= 0; y--) {

                this._levelElementsCount[y] = 0;

                for (var x = 0; x < this.width; x++) {
                    if (this.contains(x, y)) {
                        var block = this.matrix[y][x];
                        this.matrix[y][x] = false;

                        block.coordinate.y += levelsToFallDown[y];
                        this._addBlock(block);
                    }
                }
            }
        }
        return rowsCollapsed;
    };
    Earth.prototype.toString = function () {
        var result = "";

        for (var y = 0; y < this.height; y++) {

            result += this._levelElementsCount[y] + " : ";

            for (var x = 0; x < this.width; x++) {
                if (this.contains(x, y)) {
                    result += "*";
                }
                else {
                    result += ".";
                }
            }
            result += "\n";
        }

        result += "getBody: ";
        for (var i = 0; i < this.getBody.length; i++) {
            result += this.getBody[i].coordinate.toString() + " ";
        }

        return result;
    };


    tetris.Earth = Earth;

})();